package io.gitee.zhangbinhub.acp.cloud.oauth.conf

import cn.dev33.satoken.context.SaHolder
import cn.dev33.satoken.oauth2.SaOAuth2Manager
import cn.dev33.satoken.oauth2.consts.GrantType
import cn.dev33.satoken.oauth2.consts.SaOAuth2Consts
import cn.dev33.satoken.oauth2.data.model.loader.SaClientModel
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception
import cn.dev33.satoken.oauth2.function.SaOAuth2DoLoginHandleFunction
import cn.dev33.satoken.stp.StpUtil
import cn.dev33.satoken.stp.parameter.SaLoginParameter
import cn.dev33.satoken.util.SaResult
import io.gitee.zhangbinhub.acp.cloud.resource.server.conf.AcpCloudResourceServerConfiguration
import org.noear.solon.annotation.Configuration
import org.noear.solon.annotation.Init
import org.noear.solon.annotation.Inject

@Configuration
class AcpOauthServerAutoConfiguration(
    @Inject private val acpCloudResourceServerConfiguration: AcpCloudResourceServerConfiguration
) {
    @Init
    fun configOAuth2Server() {
        SaOAuth2Manager.getServerConfig().let { saOAuth2ServerConfig ->
            mutableListOf<SaClientModel>().apply {
                this.add(
                    SaClientModel()
                        .setClientId("test")
                        .setClientSecret("test_sc")
                        .setClientTokenTimeout(600) // 单位秒
                        .setLowerClientTokenTimeout(600) // 单位秒
                        .setAccessTokenTimeout(600) // 单位秒
                        .setRefreshTokenTimeout(86400) // 单位秒
                        .addContractScopes("ALL", "TEST")
                        .addAllowGrantTypes(GrantType.client_credentials, GrantType.refresh_token, GrantType.password)
                )
            }.associateBy { it.clientId }.apply {
                saOAuth2ServerConfig.setClients(this)
            }.apply {
                saOAuth2ServerConfig.doLoginHandle = SaOAuth2DoLoginHandleFunction { name: String?, pwd: String? ->
                    if ("user" == name && "user" == pwd) {
                        val clientId = SaHolder.getRequest().getParam(SaOAuth2Consts.Param.client_id)
                        StpUtil.logout(name, clientId)
                        StpUtil.login(
                            name, SaLoginParameter()
                                .setTimeout(86400)// 单位秒，需和RefreshTokenTimeout一致
                                .setDeviceType(clientId)
                        )
                        SaResult.ok()
                    } else {
                        throw SaOAuth2Exception("账号名或密码错误")
                    }
                }
            }
        }

        SaOAuth2Consts.Api.authorize = "/oauth/authorize"
        SaOAuth2Consts.Api.token = "/oauth/token"
        SaOAuth2Consts.Api.refresh = "/oauth/refresh"
        SaOAuth2Consts.Api.revoke = "/oauth/revoke"
        SaOAuth2Consts.Api.client_token = "/oauth/client_token"
        SaOAuth2Consts.Api.doLogin = "/oauth/doLogin"
        SaOAuth2Consts.Api.doConfirm = "/oauth/doConfirm"
    }
}